package com.ada.config;

import com.ada.io.Resources;
import com.ada.pojo.Configuration;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.beans.PropertyVetoException;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

public class XMLConfigBuilder {

    private Configuration configuration;

    public XMLConfigBuilder() {
        this.configuration = new Configuration();
    }

    //使用dom4j将配置文件进行解析，封装configuration
    public Configuration parseConfig(InputStream inputStream) throws DocumentException, PropertyVetoException, IOException {
        Document document = new SAXReader().read(inputStream);
        //根对象<configuration>
        Element rootElement = document.getRootElement();
        List<Element> list = rootElement.selectNodes("//property");
        Properties properties = new Properties();
        for (Element element : list) {
            String name = element.attributeValue("name");
            String value = element.attributeValue("value");
            properties.setProperty(name,value);
        }
        //c3p0连接池对象
        ComboPooledDataSource comboPooledDataSource=new ComboPooledDataSource();
        comboPooledDataSource.setDriverClass(properties.getProperty("driverClass"));
        comboPooledDataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
        comboPooledDataSource.setUser(properties.getProperty("username"));
        comboPooledDataSource.setPassword(properties.getProperty("password"));

        configuration.setDataSource(comboPooledDataSource);

        //mapper.xml解析：拿到路径，得到字节输入流，dom4j解析
        List<Element> mapperList = rootElement.selectNodes("//mapper");
        for (Element element : mapperList) {
            String mapperPath = element.attributeValue("resource");
            InputStream resourceAsSteam = Resources.getResourceAsSteam(mapperPath);
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
            xmlMapperBuilder.parse(resourceAsSteam);
        }

        List<Element> packageMapperList = rootElement.selectNodes("//package");
        for (Element element : packageMapperList) {
            String packagePath = getPackagePath(element.attributeValue("name"));
            String path = getPackagePath(packagePath);
            List<String> names = new ArrayList<String>();
            for (String file : list(path)) {
                if(file.endsWith("class")){
                    String className = file.substring(0, file.indexOf('.')).replace('/', '.');
                    names.add(className);
                }
            }
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            for (String name : names) {
                try {
                    AnnotationMapperBuilder annotationMapperBuilder = new AnnotationMapperBuilder(configuration);
                    annotationMapperBuilder.parse(classLoader.loadClass(name));
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        }
        return configuration;
    }
    //获取包路径
    protected String getPackagePath(String packageName) {
        return packageName == null ? null : packageName.replace('.', '/');
    }
    //列出目录下所有文件
    public List<String> list(String path) throws IOException {
        List<String> lines = new ArrayList<String>();
        for (URL url : getResources(path)) {
            InputStream is = url.openStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            for (String line; (line = reader.readLine()) != null;) {
                if (getResources(path + "/" + line).isEmpty()) {
                   continue;
                }
                lines.add(path + "/" + line);
            }
        }
        return lines;
    }
    //解析路径到url
    protected static List<URL> getResources(String path) throws IOException {
        return Collections.list(Thread.currentThread().getContextClassLoader().getResources(path));
    }
}
